# !/usr/bin/env python
# -*-coding:utf-8 -*-

"""
# Author     ：skyTree
# version    ：python 3.11
# Description：用户模型的curd操作
"""
from core.Utils import hash_password
from schemas.user import UserCreateSchema, UserEditSchema, UserOutSchema, RoleSchema
from models.base import User, Role, Menu
from fastapi import HTTPException
import re


async def check_user_exist(name: str = None, phone: str = None, email: str = None):
    if name and await User.exists(name=name):
        raise HTTPException(status_code=422, detail="用户已存在!")
    if phone:
        if not re.match(r"^1[3-9]\d{9}$", phone):
            raise HTTPException(status_code=422, detail="手机号格式错误!")
        if await User.exists(phone=phone):
            raise HTTPException(status_code=422, detail="手机号已存在!")
    if email:
        if not re.match(r"^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$", email):
            raise HTTPException(status_code=422, detail="邮箱格式错误!")
        if await User.exists(email=email):
            raise HTTPException(status_code=422, detail="邮箱已存在!")


async def get_permissions_list(uid: int):
    permissions_list = [dict(menu)['scopes'] for menu in await Menu.filter(roles__users__id=uid).all()]
    return permissions_list


async def add_user_curd(user: UserCreateSchema) -> UserOutSchema:
    await check_user_exist(name=user.name, phone=user.phone, email=user.email)
    if user.password != user.confirm_password:
        raise HTTPException(status_code=422, detail="密码不一致!")
    if user.role:
        if not await Role.exists(id=user.role):
            raise HTTPException(status_code=422, detail="你要绑定的角色不存在!")
    role_obj = await Role.get_or_none(id=user.role)
    password = hash_password(user.password)
    user.password = password
    create_user = await User.create(name=user.name, password=password, nick_name=user.nick_name, phone=user.phone,
                                    email=user.email)

    await create_user.roles.add(role_obj)
    await create_user.save()
    # 获取用户关联的所有角色信息
    roles = await create_user.roles.all()

    # 创建角色对象的 RoleSchema 实例列表
    role_schemas = [
        RoleSchema(id=role.id, name=role.name, desc=role.desc) for role in roles
    ]
    return UserOutSchema(**dict(create_user), role=role_schemas,
                         permissionsList=await get_permissions_list(create_user.id))


async def edit_user_curd(user: UserEditSchema) -> UserOutSchema:
    user_obj = await User.get_or_none(id=user.id)
    if not user_obj:
        raise HTTPException(status_code=422, detail="用户不存在!")
    role_obj = ''
    if user.role:
        role_obj = await Role.get_or_none(id=user.role)
        if not role_obj:
            raise HTTPException(status_code=422, detail="你要绑定的角色不存在!")
    if user.phone:
        if user.phone != user_obj.phone and await User.exists(phone=user.phone):
            raise HTTPException(status_code=422, detail="手机号已存在!")
        if not re.match(r"^1[3-9]\d{9}$", user.phone):
            raise HTTPException(status_code=422, detail="手机号格式错误!")
    if user.email:
        if user.email != user_obj.email and await User.exists(email=user.email):
            raise HTTPException(status_code=422, detail="邮箱已存在!")
        if not re.match(r"^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$", user.email):
            raise HTTPException(status_code=422, detail="邮箱格式错误!")
    await user_obj.fetch_related('roles')
    await user_obj.update_from_dict(dict(user))
    if role_obj in await user_obj.roles:
        raise HTTPException(status_code=422, detail="该用户已绑定该角色!")
    await user_obj.roles.add(role_obj)
    await user_obj.save()

    # 获取用户关联的所有角色信息
    roles = await user_obj.roles.all()

    # 创建角色对象的 RoleSchema 实例列表
    role_schemas = [
        RoleSchema(id=role.id, name=role.name, desc=role.desc) for role in roles
    ]
    return UserOutSchema(**dict(user_obj), role=role_schemas, permissionsList=await get_permissions_list(user_obj.id))
